package com.xquant.pricing.calc.service.impl.otcOption.split;

import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.xquant.common.core.constant.DictConstant;
import com.xquant.pricing.calc.entity.CalcEngineParam4Simple;
import com.xquant.pricing.calc.entity.simple.*;
import com.xquant.pricing.common.utils.StringUtils;
import com.xquant.pricing.utils.DateUtils;
import com.xquant.common.engine.xPP.request.CalcEngineParam;
import com.xquant.common.engine.xPP.request.CalcPricingParam;
import com.xquant.common.engine.xPP.request.Instrument;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.List;


/**
 * 功能说明：双鲨期权拆分
 * 编写作者：botao.yu
 * 开发日期：2021/11/12 13:47
 * 修改记录：修改日期   修改人    修改内容
 */
@Component
public class CalcCommonService4OtcOptionSplit4DoubleShark implements CalcCommonService4OtcOptionSplit {

    @Override
    public CalcEngineParam split(CalcEngineParam4Simple sourceCalcEngineParam) {
        CalcEngineParam engineParam = new CalcEngineParam();
        engineParam.setPriority("h");
        engineParam.setLocalLog("1");
        Instrument instrument = new Instrument();
        Record record = sourceCalcEngineParam.getRecord();
        BaseInfo baseInfo = record.getBaseInfo();
        OptionTrade OptionTrade = record.getOptionTrade();

        List<PremiumItem> premiumList = null;
        if (OptionTrade != null) {
            premiumList = OptionTrade.getPremium();
        }
        List<OptionLeg> legDataList = OptionTrade.getOptionLegs();
        LegData legData = null;
        if (legDataList.size() > 0) {
            legData = legDataList.get(0).getLegData();
        }
        BigDecimal annualRatio = getAnnualRatio(getCalcDate(sourceCalcEngineParam), legData.getEffectiveDate(), DateUtils.addDate(legData.getTerminationDate(), 1), transferBasic(legData.getDayCounter(), legData.getIfAnnual()));
        legData.setAnnualRatio(annualRatio);
        if (legData != null) {
            int i = 0;
            JSONObject termData = new JSONObject();
            JSONArray legsJsonArray = new JSONArray();
            JSONArray custLegsArray = new JSONArray();
            termData.put("notional", legData.getNotional());
            termData.put("notionalCurrency", "CNY");
            termData.put("term", legData.getTerm());
            termData.put("settlementType", "Cash");
            termData.put("settlementCurrency", "CNY");
            termData.put("effectiveDate", legData.getEffectiveDate());
            termData.put("effectiveDateConv", "NONE");
            termData.put("terminationDate", legData.getTerminationDate());
            termData.put("terminationDateConv", "NONE");
            termData.put("terminationDateCalendar", "CHINA_EX");
            legData.setUnderlyerId(getInstructionId((String) legData.getUnderlyerId()));
            String[] underLyerArray = {legData.getUnderlyerId()};
            termData.put("underlyerIds", underLyerArray);
            termData.put("calendars", new String[]{"CHINA_EX"});
            termData.put("legs", legsJsonArray);
            if (DictConstant.OBSERVE_TYPE.AMERICAN.equals(legData.getObserveType())) {
                //美式:双障碍+双障碍+双不触碰的组合期权传入计算服务
                custLegsArray.addAll(SplitAmericaOption(legData, legsJsonArray, sourceCalcEngineParam.getHeader().getTimestmp()));
            } else {
                //欧式拆分：4条香草期权+4条二元  拼装legs和customLegs
                custLegsArray.addAll(SplitEuropeanOption(legData, legsJsonArray, sourceCalcEngineParam.getHeader().getTimestmp()));
            }
            i = custLegsArray.size() + 1;
            //期权费生成
//            for (PremiumItem p: premiumList) {
//                JSONObject feeObj=getIRSteamObj(legData,p.getPaymentAmountRate());
//                feeObj.put("legId","leg0"+i);
//                //根据期权费生成现金借贷
//                JSONObject legsJson=new JSONObject();
//                legsJson.put("legId","leg0"+i);
//                legsJson.put("payDirection",DictConstant.DIRECT.SELL);
//                legsJsonArray.add(legsJson);
//                custLegsArray.add(feeObj);
//                i++;
//            }
            termData.put("customLegs", custLegsArray);
            instrument.setTermsheet(termData);
            instrument.setProductType(DictConstant.PRODUCT_TYPE.STRATEGY);
            engineParam.setInstrument(instrument);
            CalcPricingParam calPriceParamObj = new CalcPricingParam();
            calPriceParamObj.setValueDate(getCalcDate(sourceCalcEngineParam));
            JSON.toJSONString(calPriceParamObj);
            engineParam.setCalcPricingParam(calPriceParamObj);
            return engineParam;
        }
        return null;
    }

    /**
     * 美式期权结构拆分  返回customLeg结构的数组
     *
     * @param legData
     * @return
     */
    private JSONArray SplitAmericaOption(LegData legData, JSONArray legsJsonArray, String timestmp) {
        //美式:双障碍+双障碍+双不触碰的组合期权传入计算服务
        String detailPType = ""; //看涨是向上敲出  看跌是向下敲出 在系统中传入的值都为KnockOut
        detailPType = DictConstant.KNOCK_TYPE.DOUBLE_KNOCK_OUT;
        JSONObject DOUBLE_KNOCK_1 = new JSONObject();
        //拼装第一条双障碍  高
        DOUBLE_KNOCK_1.put("participationRate", (String) legData.getParticipationRate());
        DOUBLE_KNOCK_1.put("productType", detailPType);
        DOUBLE_KNOCK_1.put("optionType", DictConstant.OPTION_DIRECT.CALL);
        DOUBLE_KNOCK_1.put("strikePercentage", (String) legData.getUpperStrikeRate());
        DOUBLE_KNOCK_1.put("strike", (String) legData.getUpperStrikePrice());
        DOUBLE_KNOCK_1.put("numberOfOptions", "1");
        DOUBLE_KNOCK_1.put("optionEntitlement", Double.parseDouble(legData.getNotional().toString()) / Double.parseDouble(legData.getSpotPrice().toString()));//标的份数=金额/标的初始价格
        DOUBLE_KNOCK_1.put("moneynessOption", "0");//是否年化
        DOUBLE_KNOCK_1.put("daycounter", "Actual/365 (Fixed)");//计息基准
        DOUBLE_KNOCK_1.put("fixingRounding", "-1");//定盘精度
        DOUBLE_KNOCK_1.put("settlementDateConv", "NONE");//结算日调整
        DOUBLE_KNOCK_1.put("settlementDateCalendar", "CHINA_EX");//结算日日历
        DOUBLE_KNOCK_1.put("settlementDateOffset", (String) legData.getSettlementDateOffset() + "D");//结算日偏移
        DOUBLE_KNOCK_1.put("legId", "leg01");//结算日日历
        JSONObject exerciseJSON = new JSONObject();
        exerciseJSON.put("type", DictConstant.EXERCISE_TYPE.EUROPEAN);
        exerciseJSON.put("conv", "NONE");//行权日调整方式
        exerciseJSON.put("calendar", "CHINA_EX");//行权日日历
        String[] exeDate = {/*legData.getEffectiveDate(),*/legData.getTerminationDate()};
        exerciseJSON.put("dates", exeDate);
        DOUBLE_KNOCK_1.put("exercise", exerciseJSON);
        //障碍结构
        JSONArray knockArray = new JSONArray();
        JSONObject knockJSON = new JSONObject();
        knockJSON.put("paymentDateOffset", (String) legData.getSettlementDateOffset() + "D");//结算日偏移
        knockJSON.put("paymentDateConv", "Unadjusted");//行权日调整方式
        knockJSON.put("paymentDateCalendar", "CHINA_EX");//行权日日历
        if (legData.getIfAnnual().equals(DictConstant.YES_NO.YES)) {
            knockJSON.put("paymentAmount", NumberUtil.mul(legData.getNotional(), legData.getLowerRebateRate(), legData.getAnnualRatio().toString()));//支付水平 取补偿收益率
        } else {
            knockJSON.put("paymentAmount", NumberUtil.mul(legData.getLowerRebateRate(), legData.getNotional()));//支付水平 取补偿收益率
        }
        //exerciseJSON.put("paymentAmount",legData);//支付金额
        JSONObject triggerJSON = new JSONObject();
        triggerJSON.put("type", DictConstant.YES_NO.YES.equals(legData.getLowerTriggerLevelInclude()) ? DictConstant.INCLUDE_TYPE.EQUALORLESS : DictConstant.INCLUDE_TYPE.LESS);
        triggerJSON.put("levelPercentage", (String) legData.getLowerTriggerRate());
        triggerJSON.put("level", (String) legData.getLowerTriggerPrice());
        knockJSON.put("trigger", triggerJSON);
        knockJSON.put("participationRate", (String) legData.getParticipationRate());
        knockJSON.put("payStyle", DictConstant.IR_PAY_STYLE.TRRIGER_PAY.equals(legData.getPayStyle()) ? DictConstant.PAY_STYLE.TRRIGER_PAY : DictConstant.PAY_STYLE.EXPIR_PAY);
        //观察结构
        JSONObject observeJSON = new JSONObject();
        //连续观察和每日观察的处理  TODO
        if (legData.getScheduleType().equals(DictConstant.SCHEDULE_TYPE.CONT_OBS)) {
            observeJSON.put("frequency", "");
            observeJSON.put("startDateConv", "");
            observeJSON.put("endDateConv", "");
            observeJSON.put("isIncludeStartDate", "");
            observeJSON.put("isIncludeEndDate", "");
            observeJSON.put("startDate", "");
            observeJSON.put("endDate", "");
            observeJSON.put("calendar", "");
        } else {
            observeJSON.put("calendar", "CHINA_EX");
            observeJSON.put("startDateConv", "NONE");
            observeJSON.put("endDateConv", "NONE");
            observeJSON.put("frequency", "1D");
            observeJSON.put("isIncludeStartDate", "1");
            observeJSON.put("isIncludeEndDate", "1");
            observeJSON.put("startDate", legData.getEffectiveDate());
            observeJSON.put("endDate", legData.getTerminationDate());
        }
        knockJSON.put("observeDates", observeJSON);
        //低价knock
        knockArray.add(knockJSON);
        //高价knock
        JSONObject knockJSON2 = JSON.parseObject(JSON.toJSONString(knockJSON));
        if (legData.getIfAnnual().equals(DictConstant.YES_NO.YES)) {
            knockJSON2.put("paymentAmount", NumberUtil.mul(legData.getNotional(), legData.getUpperRebateRate(), legData.getAnnualRatio().toString()));//支付水平 取补偿收益率
        } else {
            knockJSON2.put("paymentAmount", NumberUtil.mul(legData.getUpperRebateRate(), legData.getNotional()));//支付水平 取补偿收益率
        }
        JSONObject triggerJSON2 = new JSONObject();
        triggerJSON2.put("type", DictConstant.YES_NO.YES.equals(legData.getUpperTriggerLevelInclude()) ? DictConstant.INCLUDE_TYPE.EQUALORGREATER : DictConstant.INCLUDE_TYPE.GREATER);
        triggerJSON2.put("levelPercentage", (String) legData.getUpperTriggerRate());
        triggerJSON2.put("level", (String) legData.getUpperTriggerPrice());
        knockJSON2.put("trigger", triggerJSON2);
        knockArray.add(knockJSON2);
        DOUBLE_KNOCK_1.put("knocks", knockArray);
        //标的结构
        JSONObject underLyerJSON = new JSONObject();
        JSONArray underLyerJSONArray = new JSONArray();
        underLyerJSON.put("instrumentId", legData.getUnderlyerId());
        underLyerJSON.put("quoteType", "Close");
        underLyerJSON.put("spotPrice", legData.getSpotPrice());//行权价格
//        underLyerJSON.put("basketWeight","1"); //权重
        underLyerJSON.put("fixingDate", legData.getFixingDate());//定盘日
        underLyerJSON.put("fixingDayType", "Business");//定盘日
        underLyerJSON.put("fixingDateConv", "Preceding");//定盘日调整
        underLyerJSON.put("fixingDateCalendar", "CHINA_EX");//定盘日日历
        underLyerJSONArray.add(underLyerJSON);
        DOUBLE_KNOCK_1.put("underlyers", underLyerJSONArray);
        JSONArray custLegsArray = new JSONArray();
        custLegsArray.add(DOUBLE_KNOCK_1);

        //knockout 2
        String DOUBLE_KNOCK_1_jsonString = JSON.toJSONString(DOUBLE_KNOCK_1);
        JSONObject DOUBLE_KNOCK_2 = JSON.parseObject(DOUBLE_KNOCK_1_jsonString);
        DOUBLE_KNOCK_2.put("optionType", DictConstant.OPTION_DIRECT.PUT);
        DOUBLE_KNOCK_2.put("legId", "leg02");
        DOUBLE_KNOCK_2.put("strikePercentage", (String) legData.getLowerStrikeRate());
        DOUBLE_KNOCK_2.put("strike", (String) legData.getLowerStrikePrice());
        JSONArray knockscp = JSON.parseArray(JSON.toJSONString(DOUBLE_KNOCK_2.get("knocks")));
        JSONArray knocks2 = new JSONArray();
        knockscp.forEach(knock -> {
//            knock=JSON.parseObject(knock.toString());
            knock = (JSONObject) knock;
            JSONObject k = (JSONObject) knock;
            k.put("paymentAmount", "0");
            k.put("paymentAmountPecentage", "0");
            knocks2.add(k);
        });
        DOUBLE_KNOCK_2.put("knocks", knocks2);
        custLegsArray.add(DOUBLE_KNOCK_2);
        //创建DoubleTouch
        JSONObject DoubleTouch = new JSONObject();
        DoubleTouch.put("participationRate", (String) legData.getParticipationRate());
        DoubleTouch.put("productType", DictConstant.OPTION_TYPE.DOUBLENOTOUCH.getCode());
        DoubleTouch.put("optionType", DictConstant.OPTION_DIRECT.CALL);
//        DoubleTouch.put("strikePercentage",(String) legData.getLowerStrikeRate());
        DoubleTouch.put("numberOfOptions", "1");
        DoubleTouch.put("optionEntitlement", Double.parseDouble(legData.getNotional().toString()) / Double.parseDouble(legData.getSpotPrice().toString()));//标的份数=金额/标的初始价格
        DoubleTouch.put("moneynessOption", "0");//是否年化
        DoubleTouch.put("daycounter", "Actual/365 (Fixed)");//计息基准
        DoubleTouch.put("fixingRounding", "-1");//定盘精度
        DoubleTouch.put("settlementDateConv", "NONE");//结算日调整
        DoubleTouch.put("settlementDateCalendar", "CHINA_EX");//结算日日历
        DoubleTouch.put("settlementDateOffset", (String) legData.getSettlementDateOffset() + "D");//结算日偏移
        DoubleTouch.put("legId", "leg03");//结算日日历
        String s = JSON.toJSONString(underLyerJSONArray);
        DoubleTouch.put("underlyers", JSON.parse(s));//结算日日历

        JSONArray touchs = new JSONArray();
        JSONObject lowTouch = new JSONObject();
        lowTouch.put("observeDates", JSON.parse(JSON.toJSONString(observeJSON)));
        JSONObject lowTrigger = new JSONObject();
        lowTrigger.put("type", DictConstant.INCLUDE_TYPE.EQUALORLESS);
        lowTrigger.put("level", legData.getLowerTriggerPrice());
        lowTrigger.put("levelPercentage", legData.getLowerTriggerRate());
        lowTouch.put("trigger", lowTrigger);
        lowTouch.put("participationRate", (String) legData.getParticipationRate());
        if ("1".equals(legData.getIfAnnual())) {
            lowTouch.put("paymentAmountPecentage", NumberUtil.mul(legData.getMinYield(), legData.getAnnualRatio().toString()));
            lowTouch.put("paymentAmount", NumberUtil.mul(legData.getNotional(), lowTouch.getString("paymentAmountPecentage")));//支付水平 取补偿收益率
        } else {
            lowTouch.put("paymentAmount", NumberUtil.mul(legData.getMinYield(), legData.getNotional()));
            lowTouch.put("paymentAmountPecentage", legData.getMinYield());
        }
        lowTouch.put("paymentDate", legData.getTerminationDate());
        lowTouch.put("paymentDateOffset", (String) legData.getSettlementDateOffset() + "D");
        lowTouch.put("observeType", "");
        lowTouch.put("paymentDateConv", "NONE");
        lowTouch.put("paymentDateCalendar", "CHINA_EX");
        JSONObject uperTouch = new JSONObject();
        uperTouch.put("observeDates", JSON.parse(JSON.toJSONString(observeJSON)));
        uperTouch.put("participationRate", (String) legData.getParticipationRate());
        if ("1".equals(legData.getIfAnnual())) {
            uperTouch.put("paymentAmountPecentage", NumberUtil.mul(legData.getMinYield(), legData.getAnnualRatio().toString()));
            uperTouch.put("paymentAmount", NumberUtil.mul(legData.getNotional(), lowTouch.getString("paymentAmountPecentage")));//支付水平 取补偿收益率
        } else {
            uperTouch.put("paymentAmount", NumberUtil.mul(legData.getMinYield(), legData.getNotional()));
            uperTouch.put("paymentAmountPecentage", legData.getMinYield());
        }
        uperTouch.put("paymentDate", legData.getTerminationDate());
        uperTouch.put("paymentDateOffset", (String) legData.getSettlementDateOffset() + "D");
        uperTouch.put("observeType", "");
        uperTouch.put("paymentDateConv", "NONE");
        uperTouch.put("paymentDateCalendar", "CHINA_EX");
        JSONObject uperTrigger = new JSONObject();
        uperTrigger.put("type", DictConstant.INCLUDE_TYPE.EQUALORGREATER);
        uperTrigger.put("level", legData.getUpperTriggerPrice());
        uperTrigger.put("levelPercentage", legData.getUpperTriggerRate());
        uperTouch.put("trigger", uperTrigger);
        touchs.add(lowTouch);
        touchs.add(uperTouch);
        DoubleTouch.put("touchs", touchs);
        DoubleTouch.put("exercise", JSON.parse(JSON.toJSONString(exerciseJSON)));
        custLegsArray.add(DoubleTouch);
        //记录腿号及方向
        JSONObject legsJSON1 = new JSONObject();
        legsJSON1.put("legId", "leg01");
        legsJSON1.put("payDirection", DictConstant.IR_DIRECT.SELL.equals(legData.getTrdType()) ? DictConstant.DIRECT.SELL : DictConstant.DIRECT.BUY);
        legsJsonArray.add(legsJSON1);
        JSONObject legsJSON2 = new JSONObject();
        legsJSON2.put("legId", "leg02");
        legsJSON2.put("payDirection", DictConstant.IR_DIRECT.SELL.equals(legData.getTrdType()) ? DictConstant.DIRECT.SELL : DictConstant.DIRECT.BUY);
        legsJsonArray.add(legsJSON2);
        JSONObject legsJSON3 = new JSONObject();
        legsJSON3.put("legId", "leg03");
        legsJSON3.put("payDirection", DictConstant.IR_DIRECT.SELL.equals(legData.getTrdType()) ? DictConstant.DIRECT.SELL : DictConstant.DIRECT.BUY);
        legsJsonArray.add(legsJSON3);

        return custLegsArray;
    }

    /**
     * 欧式期权结构拆分  返回customLeg结构的数组
     *
     * @param legData
     * @param legsJsonArray
     * @return
     */
    private JSONArray SplitEuropeanOption(LegData legData, JSONArray legsJsonArray, String timestmp) {
        //4条香草期权+4条二元
        JSONArray custLegsArray = new JSONArray();
        //第一条为买入看跌 低行权价
        JSONObject custLegsJSON = new JSONObject();
        custLegsJSON.put("participationRate", (String) legData.getParticipationRate());
        custLegsJSON.put("productType", DictConstant.OPTION_TYPE.VANILLA.getCode());
        custLegsJSON.put("optionType", DictConstant.OPTION_DIRECT.PUT);
        custLegsJSON.put("strikePercentage", (String) legData.getLowerStrikeRate());
        custLegsJSON.put("numberOfOptions", "1");
        custLegsJSON.put("optionEntitlement", Double.parseDouble(legData.getNotional().toString()) / Double.parseDouble(legData.getSpotPrice().toString()));//标的份数=金额/标的初始价格
        custLegsJSON.put("moneynessOption", legData.getIfAnnual());//是否年化
        custLegsJSON.put("daycounter", "Actual/365 (Fixed)");//计息基准
        custLegsJSON.put("fixingRounding", "-1");//定盘精度
        custLegsJSON.put("settlementDateConv", "NONE");//结算日调整
        custLegsJSON.put("settlementDateCalendar", "CHINA_EX");//结算日日历
        custLegsJSON.put("settlementDateOffset", (String) legData.getSettlementDateOffset() + "D");//结算日偏移
        custLegsJSON.put("legId", "leg01");//结算日日历
        JSONObject exerciseJSON = new JSONObject();
        exerciseJSON.put("type", "European");//默认欧式
        exerciseJSON.put("conv", "NONE");//行权日调整方式
        exerciseJSON.put("calendar", "CHINA_EX");//行权日日历
        String[] exeDate = {legData.getTerminationDate()};//行权日
        exerciseJSON.put("dates", exeDate);
        custLegsJSON.put("exercise", exerciseJSON);
        JSONObject underLyerJSON = new JSONObject();
        JSONArray underLyerJSONArray = new JSONArray();
        underLyerJSON.put("instrumentId", legData.getUnderlyerId());
        underLyerJSON.put("quoteType", "Close");
        underLyerJSON.put("spotPrice", legData.getSpotPrice());//行权价格
//        underLyerJSON.put("basketWeight","1"); //权重
        underLyerJSON.put("fixingDate", legData.getFixingDate());//定盘日
        underLyerJSON.put("fixingDateConv", "Preceding");//定盘日调整
        underLyerJSON.put("fixingDateCalendar", "CHINA_EX");//定盘日日历
        underLyerJSONArray.add(underLyerJSON);
        custLegsJSON.put("underlyers", underLyerJSONArray);
        custLegsArray.add(custLegsJSON);
        //记录腿号及方向
        JSONObject legsJSON = new JSONObject();
        legsJSON.put("legId", "leg01");
        legsJSON.put("payDirection", DictConstant.IR_DIRECT.SELL.equals(legData.getTrdType()) ? DictConstant.DIRECT.SELL : DictConstant.DIRECT.BUY);
        legsJsonArray.add(legsJSON);
        //第二条 为买入看涨 高行权价
        JSONObject custLegsJSON2 = JSON.parseObject(JSON.toJSONString(custLegsJSON));
        custLegsJSON2.put("legId", "leg02");
        custLegsJSON2.put("optionType", DictConstant.OPTION_DIRECT.CALL);
        custLegsJSON2.put("strikePercentage", (String) legData.getUpperStrikeRate());
        custLegsJSON2.put("moneynessOption", legData.getIfAnnual());//是否年化
        custLegsJSON2.put("daycounter", "Actual/365 (Fixed)");//计息基准
        custLegsArray.add(custLegsJSON2);
        //记录腿号及方向
        JSONObject legsJSON2 = JSON.parseObject(JSON.toJSONString(legsJSON));
        legsJSON2.put("legId", "leg02");
        legsJsonArray.add(legsJSON2);
        //第三条 为买卖出看跌 低障碍价
        JSONObject custLegsJSON3 = JSON.parseObject(JSON.toJSONString(custLegsJSON));
        custLegsJSON3.put("legId", "leg03");
        custLegsJSON3.put("optionType", DictConstant.OPTION_DIRECT.PUT);
        custLegsJSON3.put("strikePercentage", (String) legData.getLowerTriggerRate());
        custLegsJSON3.put("moneynessOption", legData.getIfAnnual());//是否年化
        custLegsJSON3.put("daycounter", "Actual/365 (Fixed)");//计息基准
        custLegsArray.add(custLegsJSON3);
        //记录腿号及方向
        JSONObject legsJSON3 = JSON.parseObject(JSON.toJSONString(legsJSON));
        legsJSON3.put("legId", "leg03");
        legsJSON3.put("payDirection", DictConstant.IR_DIRECT.SELL.equals(legData.getTrdType()) ? DictConstant.DIRECT.BUY : DictConstant.DIRECT.SELL);
        legsJsonArray.add(legsJSON3);
        //第四条 为买卖出看涨 高障碍价
        JSONObject custLegsJSON4 = JSON.parseObject(JSON.toJSONString(custLegsJSON));
        custLegsJSON4.put("legId", "leg04");
        custLegsJSON4.put("optionType", DictConstant.OPTION_DIRECT.CALL);
        custLegsJSON4.put("strikePercentage", (String) legData.getUpperTriggerRate());
        custLegsJSON4.put("moneynessOption", legData.getIfAnnual());//是否年化
        custLegsJSON4.put("daycounter", "Actual/365 (Fixed)");//计息基准
        custLegsArray.add(custLegsJSON4);
        //记录腿号及方向
        JSONObject legsJSON4 = JSON.parseObject(JSON.toJSONString(legsJSON));
        legsJSON4.put("legId", "leg04");
        legsJSON4.put("payDirection", DictConstant.IR_DIRECT.SELL.equals(legData.getTrdType()) ? DictConstant.DIRECT.BUY : DictConstant.DIRECT.SELL);
        legsJsonArray.add(legsJSON4);
        //第五条 为卖出看跌 二元 低障碍价 最低收益率为支付水平
        JSONObject custLegsJSON5 = new JSONObject();
        custLegsJSON5.put("participationRate", (String) legData.getParticipationRate());
        custLegsJSON5.put("productType", DictConstant.OPTION_TYPE.DIGITAL.getCode());
        custLegsJSON5.put("optionType", DictConstant.OPTION_DIRECT.PUT);
        custLegsJSON5.put("strikePercentage", (String) legData.getLowerTriggerRate());
        custLegsJSON5.put("numberOfOptions", "1");
        custLegsJSON5.put("optionEntitlement", Double.parseDouble(legData.getNotional().toString()) / Double.parseDouble(legData.getSpotPrice().toString()));//标的份数=金额/标的初始价格
        custLegsJSON5.put("moneynessOption", legData.getIfAnnual());//是否年化
        custLegsJSON.put("daycounter", "Actual/365 (Fixed)");//计息基准
        custLegsJSON5.put("fixingRounding", "-1");//定盘精度
        custLegsJSON5.put("settlementDateConv", "NONE");//结算日调整
        custLegsJSON5.put("settlementDateCalendar", "CHINA_EX");//结算日日历
        custLegsJSON5.put("settlementDateOffset", (String) legData.getSettlementDateOffset() + "D");//结算日偏移
        custLegsJSON5.put("legId", "leg05");//结算日日历
        custLegsJSON5.put("exercise", JSON.parseObject(JSON.toJSONString(exerciseJSON)));
        custLegsJSON5.put("moneynessOption", legData.getIfAnnual());//是否年化
        custLegsJSON5.put("daycounter", "Actual/365 (Fixed)");//计息基准
        //二元结构
        JSONObject digitalJSON = new JSONObject();
        digitalJSON.put("paymentDateOffset", (String) legData.getSettlementDateOffset() + "D");//结算日偏移
        digitalJSON.put("paymentDateConv", "Unadjusted");//行权日调整方式
        digitalJSON.put("paymentDateCalendar", "CHINA_EX");//行权日日历
        digitalJSON.put("moneynessOption", legData.getIfAnnual());//是否年化
        digitalJSON.put("daycounter", "Actual/365 (Fixed)");//计息基准
        if ("1".equals(legData.getIfAnnual())) {
            digitalJSON.put("paymentAmount", NumberUtil.mul(legData.getMinYield(), legData.getNotional(), legData.getAnnualRatio().toString()));//支付水平 取补偿收益率
        } else {
            digitalJSON.put("paymentAmountPecentage", legData.getMinYield());//支付水平 取补偿收益率
        }
        JSONObject triggerJSON = new JSONObject();
        if (StringUtils.isNotNull(legData.getLowerTriggerLevelInclude()) && legData.getLowerTriggerLevelInclude().equals(DictConstant.YES_NO.YES)) {
            triggerJSON.put("type", "EqualOrLess");
        } else {
            triggerJSON.put("type", "Less");
        }
        triggerJSON.put("levelPercentage", (String) legData.getLowerTriggerRate());
        digitalJSON.put("trigger", triggerJSON);
        custLegsJSON5.put("digital", digitalJSON);
        //标的结构
        JSONArray underLyerJSONArray2 = new JSONArray();
        JSONObject underLyerJSON2 = JSON.parseObject(JSON.toJSONString(underLyerJSON));
        underLyerJSONArray2.add(underLyerJSON2);
        custLegsJSON5.put("underlyers", underLyerJSONArray2);
        custLegsArray.add(custLegsJSON5);
        //记录腿号及方向
        JSONObject legsJSON5 = JSON.parseObject(JSON.toJSONString(legsJSON));
        legsJSON5.put("legId", "leg05");
        legsJSON5.put("payDirection", DictConstant.IR_DIRECT.SELL.equals(legData.getTrdType()) ? DictConstant.DIRECT.BUY : DictConstant.DIRECT.SELL);
        legsJsonArray.add(legsJSON5);
        //第六条  为卖出看涨 二元 高障碍价 最低收益率为支付水平
        JSONObject custLegsJSON6 = JSON.parseObject(JSON.toJSONString(custLegsJSON5));
        custLegsJSON6.put("strikePercentage", (String) legData.getUpperTriggerRate());
        custLegsJSON6.put("legId", "leg06");
        custLegsJSON6.put("moneynessOption", legData.getIfAnnual());//是否年化
        custLegsJSON6.put("daycounter", "Actual/365 (Fixed)");//计息基准
        custLegsJSON6.put("optionType", DictConstant.OPTION_DIRECT.CALL);
        JSONObject triggerJSON2 = JSON.parseObject(JSON.toJSONString(triggerJSON));
        JSONObject digitalJSON2 = JSON.parseObject(JSON.toJSONString(digitalJSON));
        triggerJSON2.put("levelPercentage", (String) legData.getUpperTriggerRate());
        triggerJSON2.put("type", "EqualOrGreater");
        if (StringUtils.isNotNull(legData.getUpperTriggerLevelInclude()) && legData.getUpperTriggerLevelInclude().equals(DictConstant.YES_NO.YES)) {
            triggerJSON.put("type", "EqualOrGreater");
        } else {
            triggerJSON.put("type", "EGreater");
        }
        digitalJSON2.put("trigger", triggerJSON2);
        //支付水平 最低收益率
        if ("1".equals(legData.getIfAnnual())) {
            digitalJSON.put("paymentAmount", NumberUtil.mul(legData.getMinYield(), legData.getNotional(), legData.getAnnualRatio().toString()));//支付水平 取补偿收益率
        } else {
            digitalJSON.put("paymentAmountPecentage", legData.getMinYield());
        }
        custLegsJSON6.put("digital", digitalJSON2);
        custLegsArray.add(custLegsJSON6);
        //记录腿号及方向
        JSONObject legsJSON6 = JSON.parseObject(JSON.toJSONString(legsJSON));
        legsJSON6.put("legId", "leg06");
        legsJSON6.put("payDirection", DictConstant.IR_DIRECT.SELL.equals(legData.getTrdType()) ? DictConstant.DIRECT.BUY : DictConstant.DIRECT.SELL);
        legsJsonArray.add(legsJSON6);
        //第七条  为买入出看涨 二元 低障碍价
        JSONObject custLegsJSON7 = JSON.parseObject(JSON.toJSONString(custLegsJSON5));
        JSONObject triggerJSON3 = JSON.parseObject(JSON.toJSONString(triggerJSON));
        JSONObject digitalJSON3 = JSON.parseObject(JSON.toJSONString(digitalJSON));
        triggerJSON3.put("levelPercentage", (String) legData.getLowerTriggerRate());
        //支付水平 (低行权价-低障碍价)*期权参与率*久期乘数-低补偿*补偿参与率
        BigDecimal digitalJSON3paymentAmountPecentage = NumberUtil.sub(NumberUtil.mul(NumberUtil.sub(legData.getLowerStrikeRate(), legData.getLowerTriggerRate()).toString(), legData.getParticipationRate()), NumberUtil.mul(legData.getLowerRebateRate(), legData.getRebateParticipationRate()));
        if ("1".equals(legData.getIfAnnual())) {
//            BigDecimal paymentAmount = digitalJSON3paymentAmountPecentage.multiply(legData.getAnnualRatio()).multiply(BigDecimal.valueOf(Long.parseLong(legData.getSpotPrice())));
//            digitalJSON3.put("paymentAmount",paymentAmount);
            digitalJSON3.put("paymentAmount", NumberUtil.mul(legData.getMinYield(), legData.getNotional(), legData.getAnnualRatio().toString()));//支付水平 取补偿收益率

        } else {
            digitalJSON3.put("paymentAmountPecentage", NumberUtil.sub(NumberUtil.mul(NumberUtil.sub(legData.getLowerStrikeRate(), legData.getLowerTriggerRate()).toString(), legData.getParticipationRate()), NumberUtil.mul(legData.getLowerRebateRate(), legData.getRebateParticipationRate())));

        }
        digitalJSON3.put("trigger", triggerJSON3);
        custLegsJSON7.put("optionType", DictConstant.OPTION_DIRECT.CALL);
        custLegsJSON7.put("legId", "leg07");
        custLegsJSON7.put("strikePercentage", (String) legData.getLowerTriggerRate());
        custLegsJSON7.put("digital", digitalJSON3);
        custLegsJSON7.put("moneynessOption", legData.getIfAnnual());//是否年化
        custLegsJSON7.put("daycounter", "Actual/365 (Fixed)");//计息基准
        custLegsArray.add(custLegsJSON7);
        //记录腿号及方向
        JSONObject legsJSON7 = JSON.parseObject(JSON.toJSONString(legsJSON));
        legsJSON7.put("legId", "leg07");
        legsJSON7.put("payDirection", DictConstant.IR_DIRECT.SELL.equals(legData.getTrdType()) ? DictConstant.DIRECT.SELL : DictConstant.DIRECT.BUY);
        legsJsonArray.add(legsJSON7);
        //第八条  为卖出看涨二元 高障碍价
        JSONObject custLegsJSON8 = JSON.parseObject(JSON.toJSONString(custLegsJSON5));
        JSONObject triggerJSON4 = JSON.parseObject(JSON.toJSONString(triggerJSON));
        JSONObject digitalJSON4 = JSON.parseObject(JSON.toJSONString(digitalJSON));
        triggerJSON4.put("levelPercentage", (String) legData.getUpperTriggerRate());
        //支付水平 (高障碍价-高行权价)*期权参与率*久期乘数-高补偿*补偿参与率
        BigDecimal digitalJSON4paymentAmountPecentage = NumberUtil.sub(NumberUtil.mul(NumberUtil.sub(legData.getUpperTriggerRate(), legData.getUpperStrikeRate()).toString(), legData.getParticipationRate()), NumberUtil.mul(legData.getUpperRebateRate(), legData.getRebateParticipationRate()));
        if ("1".equals(legData.getIfAnnual())) {
//            BigDecimal paymentAmount = digitalJSON4paymentAmountPecentage.multiply(BigDecimal.valueOf(Long.parseLong(legData.getSpotPrice()))).multiply(legData.getAnnualRatio());
//            digitalJSON4.put("paymentAmount",paymentAmount) ;
            digitalJSON4.put("paymentAmount", NumberUtil.mul(legData.getMinYield(), legData.getNotional(), legData.getAnnualRatio().toString()));//支付水平 取补偿收益率

        } else {
            digitalJSON4.put("paymentAmountPecentage", digitalJSON4paymentAmountPecentage);
        }
        digitalJSON4.put("trigger", triggerJSON4);
        custLegsJSON8.put("legId", "leg08");
        custLegsJSON8.put("strikePercentage", (String) legData.getUpperTriggerRate());
        custLegsJSON8.put("digital", digitalJSON4);
        custLegsJSON8.put("moneynessOption", legData.getIfAnnual());//是否年化
        custLegsJSON8.put("optionType", DictConstant.OPTION_DIRECT.CALL);
        custLegsJSON8.put("daycounter", "Actual/365 (Fixed)");//计息基准
        custLegsArray.add(custLegsJSON8);
        //记录腿号及方向
        JSONObject legsJSON8 = JSON.parseObject(JSON.toJSONString(legsJSON));
        legsJSON8.put("legId", "leg08");
        legsJSON8.put("payDirection", DictConstant.IR_DIRECT.SELL.equals(legData.getTrdType()) ? DictConstant.DIRECT.BUY : DictConstant.DIRECT.SELL);
        legsJsonArray.add(legsJSON8);
        return custLegsArray;
    }

    @Override
    public CalcEngineParam split(CalcEngineParam sourceCalcEngineParam) {
        return null;
    }

    @Override
    public String getSplitCode() {
        return DictConstant.OPTION_TYPE.DOUBLE_SHARK.getCode();
    }


}
